<template>
  <div class="content">
    <div class="nav">
      <a
        v-for="(item, index) in navs"
        :key="index"
        :class="{ active: index == active }"
        @click="scrollTo(index)"
      >
        <p>
          <span>
            {{ item }}
          </span>
        </p>
      </a>
    </div>
    <div class="cont">
      <div v-for="(item, index) in conts" :key="index" :id="'md' + index">
        <div class="img_t">
          <img :src="item.imgsrc" alt="" />
        </div>
        <div class="cont" v-if="item.cont">
          <div v-for="(t, i) in item.cont" :key="i" class="boxs">
            <h2 class="title">{{ t.title }}</h2>
            <div class="box" v-for="(x, j) in t.cont" :key="j">
              <img :src="x.imgsrc" alt="" />
              <div class="r">
                <p>{{ x.title }}</p>
                <p>￥{{ x.price }}</p>
              </div>
            </div>
          </div>
        </div>
        <div
          class="scattered"
          v-for="(item, index) in item.scattered"
          :key="index"
        >
          <h2 class="title" v-if="item.title">{{ item.title }}</h2>
          <div class="boxs_">
            <div class="box_" v-for="(y, j) in item.cont" :key="j">
              <img :src="y.imgsrc" alt="" />
              <p>{{ y.title }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import instance from "../../api/request";
export default {
  name: "ClassifyNavs",
  data() {
    return {
      // 储存数据
      active: 0,
      navs: null,
      conts: null,
    };
  },
  methods: {
    // 获取数据
    async fn() {
      let { data } = await instance.get("/index.json");
      this.navs = data.classify.nav;
      this.conts = data.classify.cont;
    },
    async onScroll() {
      // console.log("监听到了滚动");
      // 获取所有锚点元素
      const navContents = document.querySelectorAll(".content>.cont>div");
      //   console.log(navContents);
      // 所有锚点元素的 offsetTop
      const offsetTopArr = [];
      navContents.forEach((item) => {
        offsetTopArr.push(item.offsetTop);
      });
      //   console.log("每个盒子的顶部距离：", offsetTopArr);
      // 获取当前文档流的 scrollTop
      const scrollTop = document.querySelector(".content>.cont").scrollTop;
      //   console.log("文档流的顶部距离：", scrollTop);
      // 定义当前点亮的导航下标
      let navIndex = 0;
      // offsetTopArr.forEach((item, index) => {
      //   //   console.log(item,index);
      //   if (scrollTop >= item) {
      //     navIndex = index;
      //   }
      // });
      for (let n = 0; n < offsetTopArr.length; n++) {
        // 如果 scrollTop 大于等于第n个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
        // 那么此时导航索引就应该是n了
        if (scrollTop >= offsetTopArr[n]) {
          navIndex = n;
        }
      }
      // 把下标赋值给 vue 的 data
      this.active = navIndex;
      //   console.log(this.active);
    },
    // 跳转到指定索引的元素
    scrollTo(index) {
      // 获取目标的 offsetTop
      // css选择器是从 1 开始计数，我们是从 0 开始，所以要 +1
      const targetOffsetTop = document.querySelector(
        `.content>.cont>div:nth-child(${index + 1})`
      ).offsetTop;
      // 获取当前 offsetTop
      let scrollTop = document.querySelector(".content>.cont").scrollTop;
      // 定义一次跳 50 个像素，数字越大跳得越快，但是会有掉帧得感觉，步子迈大了会扯到蛋
      const STEP = 500;
      // 判断是往下滑还是往上滑
      if (scrollTop > targetOffsetTop) {
        // 往上滑
        smoothUp();
      } else {
        // 往下滑
        smoothDown();
      }
      // 定义往下滑函数
      function smoothDown() {
        // 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
        if (scrollTop < targetOffsetTop) {
          // 如果和目标相差距离大于等于 STEP 就跳 STEP
          // 否则直接跳到目标点，目标是为了防止跳过了。
          if (targetOffsetTop - scrollTop >= STEP) {
            scrollTop += STEP;
          } else {
            scrollTop = targetOffsetTop;
          }
          document.querySelector(".content>.cont").scrollTop = scrollTop;
          // 关于 requestAnimationFrame 可以自己查一下，在这种场景下，相比 setInterval 性价比更高
          requestAnimationFrame(smoothDown);
        }
      }
      // 定义往上滑函数
      function smoothUp() {
        if (scrollTop > targetOffsetTop) {
          if (scrollTop - targetOffsetTop >= STEP) {
            scrollTop -= STEP;
          } else {
            scrollTop = targetOffsetTop;
          }
          document.querySelector(".content>.cont").scrollTop = scrollTop;
          requestAnimationFrame(smoothUp);
        }
      }
    },
  },
  created() {
    this.fn();
  },
  mounted() {
    // 监听滚动事件
    document
      .querySelector(".content>.cont")
      .addEventListener("scroll", this.onScroll, false);
  },
  destroy() {
    // 必须移除监听器，不然当该vue组件被销毁了，监听器还在就会出错
    document
      .querySelector(".content>.cont")
      .removeEventListener("scroll", this.onScroll);
  },
};
</script>
<style scoped lang="less">
@import url("../../less/index.less");
.content {
  position: absolute;
  top: 54px;
  width: 7.2rem;
  padding-right: 0.2rem;
  box-sizing: border-box;
  // left: 0;
  // right: 0;
  bottom: 50px;
  overflow: hidden;
  display: flex;
  justify-content: space-between;
  .nav::-webkit-scrollbar {
    width: 0;
  }
  .nav {
    width: 24%;
    color: @classify_nav !important;
    font-size: 0.24rem;
    // overflow-y: auto;
    overflow-y: scroll;

    a {
      width: 100%;
      height: 0.9rem;
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
    }
    a.active {
      color: #000 !important;
      font-weight: bolder;
    }
    a.active::after {
      display: block;
      content: "";
      position: absolute;
      left: 0;
      width: 0.05rem;
      height: 0.28rem;
      background: @pitch;
    }
  }
  .cont {
    width: 74%;
    background: #fff;
    color: @classify_cont !important;
    padding-right: 0.1rem;
    box-sizing: border-box;
    font-size: 0.28rem;
    overflow-y: auto;
    overflow-x: hidden;
    .title {
      font-weight: bolder;
      height: 0.63rem;
      margin-top: 0.3rem;
    }
    .img_t {
      width: 100%;
      margin-bottom: 0.2rem;
      img {
        width: 100%;
      }
    }
    .cont {
      width: 100%;
      .boxs {
        width: 100%;
        .box {
          width: 100%;
          height: 1.47rem;
          background: @theme;
          padding: 0.07rem;
          box-sizing: border-box;
          margin-bottom: 0.2rem;
          display: flex;
          justify-content: space-between;
          border-radius: 16px;
          img {
            width: 1.33rem;
            height: 1.33rem;
          }
          .r {
            width: 3.66rem;
            padding: 0.2rem 0;
            box-sizing: border-box;
            flex-wrap: wrap;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            p {
              width: 100%;
              height: 0.42rem;
              overflow: hidden;
            }
          }
        }
      }
    }
    .scattered {
      width: 100%;
      .boxs_ {
        width: 100%;
        display: flex;
        justify-content: space-between;
        margin-bottom: 0.4rem;
        flex-wrap: wrap;
        .box_ {
          margin: 0.2rem 0 0.3rem 0;
          width: 1.68rem;
          display: flex;
          justify-content: center;
          align-items: center;
          flex-wrap: wrap;
          img {
            width: 1rem;
          }
          p {
            color: rgba(0, 0, 0, 0.54);
            font-size: 0.23rem;
            margin-top: 0.28rem;
          }
        }
      }
    }
  }
}
</style>